import accessTree
import os
from pypbc import *

path = os.path.dirname(__file__)


def setup():
    U = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

    q1 = get_random_prime(60)
    q2 = get_random_prime(60)

    params = Parameters(n=q1 * q2)
    paramsfile = open('./pairingparams.txt', 'w')
    paramsfile.write(str(params))

    # paramsfile = open('pairingparams.txt','r')
    # params_str = paramsfile.read()
    # params = Parameters(params_str)

    pairing = Pairing(params)
    g = Element.random(pairing, G1)

    MK = {}
    PK = {}

    y = Element.random(pairing, Zr)
    Y = (pairing.apply(g, g)) ** y  # Y=e(g,g)**y #pbc.Elemnt

    MK['y'] = y.__str__()
    PK['Y'] = Y.__str__()
    PK['g'] = g.__str__()

    # gs = Element(pairing,G1,value=g.__str__())
    # ys = Element(pairing,Zr,value=y.__int__())
    # Ys = Element(pairing,GT,value=Y.__str__())
    # print(Ys)
    # print(type(Ys))

    for i in range(1, len(U) + 1):
        t = Element.random(pairing, Zr)
        T = Element(pairing, G1, value=g ** t)  # Ti = g**c
        MK['t' + str(i)] = t.__str__()
        PK['T' + str(i)] = T.__str__()

    # publish PK on blockchian
    pkfile = open('./PK.txt', 'w')
    pkstr = str(PK)
    pkfile.write(pkstr)
    pkfile.close()

    print(MK)
    print(PK)
    # store MK in localstorage
    mkfile = open('./MK.txt', 'w')
    mkstr = str(MK)
    mkfile.write(mkstr)
    mkfile.close()

    # read MK
    # f = open('MK.txt','r')
    # mks = f.read()
    # mk = eval(mks)
    # f.seek(0)


def keygen(ACT):
    pparams = Parameters(open('pairingparams.txt', 'r').read())
    pairing = Pairing(pparams)

    PK = eval(open('PK.txt', 'r').read())
    gString = PK['g']
    g = Element(pairing, G1, value=gString)

    MK = eval(open('MK.txt', 'r').read())
    yString = MK['y']
    y = Element(pairing, Zr, value=int(yString, 16))

    ACT.poly.append(y)
    nodeShare(ACT, pairing)


def randomP(d, s, pairing):
    coef = []
    coef[0] = s
    for i in range(1, len(d)):
        coef[i] = Element.random(pairing, Zr)
    return coef


def qx(index, coef, pairing):
    res = coef[0]
    for i in range(1, len(coef)):
        exp = Element(pairing, Zr, value=i)
        res = res.__add__(coef[i].__mul__(index.__pow__(exp)))
    return res


def lagrange(i, S, x, pairing):
    res = Element.one(pairing, Zr)
    iEle = Element(pairing, Zr, value=i)
    xEle = Element(pairing, Zr, value=x)
    for j in S:
        jEle = Element(pairing.Zr, value=j)
        if (i != j):
            nume = xEle.__add__(jEle.__neg__())
            deno = iEle.__add__(jEle.__neg__())
            res = res.__mul__(nume.__mul__(deno.__pow__(-1)))
    return res

def nodeShare(nodes,n,pairing):
    if(!n.isLeaf()):
        coef = randomP(n.gate[0],n.secresShare,pairing)
        for j in range(len(n.children)):
            childNode = nodes[n.children[j]]
            childNode.secretShare = qx(Element(pairing,Zr,value=n.children[j]),coef,pairing)
            nodeShare(nodes,childNode,pairing)

def nodeRecover(nodes,n,atts,pairing):
    if(not n.isLeaf()):
        validChildrenList = []
        validChildren = []
        for j in range(len(n.children)):
            childNode = nodes[n.children[j]]
            if(nodeRecover(nodes,childNode,atts,pairing)):
                validChildrenList.append()

setup()
keygen(1)
